﻿/*
 *	Copyright (c) 2008 by Simon Baer
 * 
 *  You may use this code for whatever you want.
 */

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Windows.Forms;
using System.Drawing;

namespace TaskbarHide
{
	/// <summary>
	/// Helper class for hiding/showing the taskbar and startmenu on
	/// Windows XP and Vista.
	/// </summary>
	public static class Taskbar
	{
		[DllImport("user32.dll")]
		private static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count); 
		[DllImport("user32.dll", CharSet = CharSet.Auto)]
		private static extern bool EnumThreadWindows(int threadId, EnumThreadProc pfnEnum, IntPtr lParam);
		[DllImport("user32.dll", SetLastError = true)]
		private static extern System.IntPtr FindWindow(string lpClassName, string lpWindowName);
		[DllImport("user32.dll", SetLastError = true)]
		private static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className,  string windowTitle);
		[DllImport("user32.dll")]
		private static extern int ShowWindow(IntPtr hwnd, int nCmdShow);
		[DllImport("user32.dll")]
		private static extern uint GetWindowThreadProcessId(IntPtr hwnd, out int lpdwProcessId);

		private const int SW_HIDE = 0;
		private const int SW_SHOW = 5;

		private const string VistaStartMenuCaption = "Start";
		private static IntPtr vistaStartMenuWnd = IntPtr.Zero;
		private delegate bool EnumThreadProc(IntPtr hwnd, IntPtr lParam);

		/// <summary>
		/// Show the taskbar.
		/// </summary>
		public static void Show()
		{
			SetVisibility(true);
		}

		/// <summary>
		/// Hide the taskbar.
		/// </summary>
		public static void Hide()
		{
			SetVisibility(false);
		}

		/// <summary>
		/// Sets the visibility of the taskbar.
		/// </summary>
		public static bool Visible
		{
			set { SetVisibility(value); }
		}

		/// <summary>
		/// Hide or show the Windows taskbar and startmenu.
		/// </summary>
		/// <param name="show">true to show, false to hide</param>
		private static void SetVisibility(bool show)
		{
			// get taskbar window
			IntPtr taskBarWnd = FindWindow("Shell_TrayWnd", null);

			// try it the WinXP way first...
			IntPtr startWnd = FindWindowEx(taskBarWnd, IntPtr.Zero, "Button", "Start");
			if (startWnd == IntPtr.Zero)
			{
				// ok, let's try the Vista easy way...
				startWnd = FindWindow("Button", null);

				if (startWnd == IntPtr.Zero)
				{
					// no chance, we need to to it the hard way...
					startWnd = GetVistaStartMenuWnd(taskBarWnd);
				}
			}
			
			ShowWindow(taskBarWnd, show ? SW_SHOW : SW_HIDE);
			ShowWindow(startWnd, show ? SW_SHOW : SW_HIDE);
		}

		/// <summary>
		/// Returns the window handle of the Vista start menu orb.
		/// </summary>
		/// <param name="taskBarWnd">windo handle of taskbar</param>
		/// <returns>window handle of start menu</returns>
		private static IntPtr GetVistaStartMenuWnd(IntPtr taskBarWnd)
		{
			// get process that owns the taskbar window
			int procId;
			GetWindowThreadProcessId(taskBarWnd, out procId);

			Process p = Process.GetProcessById(procId);
			if (p != null)
			{
				// enumerate all threads of that process...
				foreach (ProcessThread t in p.Threads)
				{
					EnumThreadWindows(t.Id, MyEnumThreadWindowsProc, IntPtr.Zero);
				}
			}
			return vistaStartMenuWnd;
		}

		/// <summary>
		/// Callback method that is called from 'EnumThreadWindows' in 'GetVistaStartMenuWnd'.
		/// </summary>
		/// <param name="hWnd">window handle</param>
		/// <param name="lParam">parameter</param>
		/// <returns>true to continue enumeration, false to stop it</returns>
		private static bool MyEnumThreadWindowsProc(IntPtr hWnd, IntPtr lParam)
		{
			StringBuilder buffer = new StringBuilder(256);
			if (GetWindowText(hWnd, buffer, buffer.Capacity) > 0)
			{
				Console.WriteLine(buffer);
				if (buffer.ToString() == VistaStartMenuCaption)
				{
					vistaStartMenuWnd = hWnd;
					return false;
				}
			}
			return true;
		}
	}


    
    // new config
 public class WinApi
   {

     [DllImport("user32.dll", EntryPoint = "GetSystemMetrics")]
     public static extern int GetSystemMetrics(int which);

     [DllImport("user32.dll")]
    
    public static extern void
        SetWindowPos(IntPtr hwnd, IntPtr hwndInsertAfter,
                     int X, int Y, int width, int height, uint flags);        

    private const int SM_CXSCREEN = 0;
    private const int SM_CYSCREEN = 1;
    private static IntPtr HWND_TOP = IntPtr.Zero;
    private const int SWP_SHOWWINDOW = 64; // 0×0040

    public static int ScreenX
    {
        get { return GetSystemMetrics(SM_CXSCREEN);}
    }

    public static int ScreenY
    {
        get { return GetSystemMetrics(SM_CYSCREEN);}
    }

    public static void SetWinFullScreen(IntPtr hwnd)
    {
        SetWindowPos(hwnd, HWND_TOP, 0, 0, ScreenX, ScreenY, SWP_SHOWWINDOW);
    }
}


 public class FormState
 {
     private FormWindowState winState;
     private FormBorderStyle brdStyle;
     private bool topMost;
     private Rectangle bounds;

     private bool IsMaximized = false;

     public void Maximize(Form targetForm)
     {
         if (!IsMaximized)
         {
             IsMaximized = true;
             Save(targetForm);
             targetForm.WindowState = FormWindowState.Maximized;
             targetForm.FormBorderStyle = FormBorderStyle.None;
             targetForm.TopMost = true;
             WinApi.SetWinFullScreen(targetForm.Handle);
         }
     }

     public void Save(Form targetForm)
     {
         winState = targetForm.WindowState;
         brdStyle = targetForm.FormBorderStyle;
         topMost = targetForm.TopMost;
         bounds = targetForm.Bounds;
     }

     public void Restore(Form targetForm)
     {
         targetForm.WindowState = winState;
         targetForm.FormBorderStyle = brdStyle;
         targetForm.TopMost = topMost;
         targetForm.Bounds = bounds;
         IsMaximized = false;
     }
 }



}
